﻿//
// GNS_LoginScene.cpp
// MobileManageSys
//FuncTion 登录场景
// Created by mr.l on 16/1/12.
//
//
#include "GnsClientFrame.h"
#include "IEventBridge.h"
#include "GNS_LoginScene.h"
#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h"
#include "GNS_Common.h"
#include "GNS_PlayerMgr.h"
#include "GNS_SceneMgr.h"
#include "GnsOften.h"

USING_NS_CC;
using namespace cocostudio::timeline;
using namespace ui;

//ISocketMgr * _GameSock=nullptr;
#define winsize Director::getInstance()->getVisibleSize()

GNS_LoginScene::GNS_LoginScene()
{
    //if (//_GameSock==nullptr) {
        //_GameSock = new ISocketMgr;
    //}
    NameText=nullptr;
    PassText=nullptr;
    pInfoMakeLayer=nullptr;
    InputID=nullptr;
    InputPass=nullptr;
	flag = false;
}

GNS_LoginScene::~GNS_LoginScene()
{
//    CC_SAFE_DELETE(InputID);
//    CC_SAFE_DELETE(InputPass);
	flag = false;
    this->removeChild(InputID);
    this->removeChild(InputPass);
}

Scene* GNS_LoginScene::createScene()
{
    auto scene = Scene::create();
    
    GNS_SceneMgr::getInstance()->AddSceneLayer(LOGIN_LAYER);
    auto layer = (GNS_LoginScene*)GNS_SceneMgr::getInstance()->getSceneLayer(LOGIN_LAYER);
    scene->addChild(layer);
    
    return scene;
}

bool GNS_LoginScene::init()
{
    if ( !GNS_YJFLayer::init() )
    {
        return false;
    }

	int version = VER_MAIN * 100000 +
		VER_CHILD * 10000 +
		VER_BUILD;
	GNS_PlayerMgr::getInstance()->setCurrentVersionClient(version);
	initData();

    return true;
}

// 进入场景后，要初始化内容
void GNS_LoginScene::onEnterTransitionDidFinish()
{
	// 事件桥梁定时器
	//this->schedule(schedule_selector(GNS_LoginScene::onEventBridge), 0.08f);
}

// 离开场景前，要释放内容
void GNS_LoginScene::onExitTransitionDidStart()
{
	// 杀掉事件桥梁定时器
	this->unschedule( schedule_selector(GNS_LoginScene::onEventBridge));
}

void GNS_LoginScene::initData()
{
	auto rootNode = CSLoader::createNode("MainScene.csb");
    rootNode->setContentSize(winsize);
    ui::Helper::doLayout(rootNode);
    addChild(rootNode);
    
    auto LoginBtn = static_cast<Button*>(rootNode->getChildByName("Button_1"));
    LoginBtn->setTag(0);
    LoginBtn->addTouchEventListener(CC_CALLBACK_2(GNS_LoginScene::BtnCallBack, this));
    
    NameText= static_cast<TextField*>(rootNode->getChildByName("NameTextField"));
	if (UserDefault::getInstance()->getStringForKey("id", "")!="")
		NameText->setString(UserDefault::getInstance()->getStringForKey("id", ""));
	NameText->setVisible(false);

    PassText=static_cast<TextField*>(rootNode->getChildByName("PassText"));
	PassText->setString("");
	PassText->setVisible(false);

	_NameText = GNS_Handler::createBSEditBoxWithExistFeild(NameText, rootNode, 14, EditBox::InputMode::NUMERIC);
	if (UserDefault::getInstance()->getStringForKey("id", "") != "")
		_NameText->setText(UserDefault::getInstance()->getStringForKey("id", "").c_str());

	_PassText = GNS_Handler::createBSEditBoxWithExistFeild(PassText, rootNode, 14, EditBox::InputMode::EMAIL_ADDRESS, true, EditBox::InputFlag::PASSWORD);
    
#if 0  // 有光标这一段有问题
	InputID = createEditBox("100085", Vec2(winsize.width*0.43, winsize.height*0.62), 28, Color3B::BLACK, 12, false);
	rootNode->addChild(InputID, 12);
	InputPass = createEditBox("123456", Vec2(winsize.width*0.43, winsize.height*0.52), 28, Color3B::BLACK, 12, true);
	rootNode->addChild(InputPass);
	InputID->setString("100085");
	InputPass->setString("123456");
#endif

    auto Version = static_cast<Text*>(rootNode->getChildByName("Version"));
    Version->setString(CCGnsOften::getUtf8_DirectAssignmentInProgram(StringUtils::format("版本号:%d",GNS_PlayerMgr::getInstance()->getCurrentVersionClient())));

}

void GNS_LoginScene::BtnCallBack(cocos2d::Ref *pSender, ui::Widget::TouchEventType type)
{
    int iRes = 0;
    
    if (type==ui::Widget::TouchEventType::ENDED) {
        auto pButton = (Button*)pSender;
        int BtnTag = pButton->getTag();
        switch (BtnTag) 
		{
            case 0:
            {
				if (!checkInput())
					  return;
				if (_NameText->getText() != "")
					  UserDefault::getInstance()->setStringForKey("id", _NameText->getText());
				GnsClientFrame* pGnsClientFrame = GnsClientFrame::getInstance();	
				if (pGnsClientFrame->isClientSocketValid(MOBILE_SEVER))  //已连接上时，直接登录
                {
					login();
                }
				else
				{
					if (pInfoMakeLayer == nullptr)
					{
						pInfoMakeLayer = GNS_MakeLayer::CreateMakeLayer("加载中...");
						addMakerLayer();
					}
					this->schedule(schedule_selector(GNS_LoginScene::onEventBridge), 0.08f);
					iRes = GnsClientFrame::getInstance()->manualConnect(MOBILE_SEVER);
					assert(0 == iRes);
				}
               

				break;
            }
            case 2:
            {
#if (CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
                std::string AppDownURL = GNS_PlayerMgr::getInstance()->getUpdateURL();
                Application::getInstance()->openURL(AppDownURL);
#else
                
#endif
                break;
            }
            default:
                break;
        }
    }
}

void GNS_LoginScene::SceneJump()
{
	if (pInfoMakeLayer!= nullptr)
		pInfoMakeLayer->Show(false);
    GNS_SceneMgr::getInstance()->replaceScene(HALL_SCENE);
}

void GNS_LoginScene::LoginFile()
{
	if (pInfoMakeLayer != nullptr)
		pInfoMakeLayer->Show(false);
}

void GNS_LoginScene::GameUpdae()
{
    auto pUpdatePopWnd =  PopWndLayer::createScene("Popwnd.png", "PageClose.png");
    pUpdatePopWnd->SetTitleWithUTF("升级提示!");
    std::string ContentText = StringUtils::format("发现新版本[%d],点击确认升级!",GNS_PlayerMgr::getInstance()->getServerVersion());
    pUpdatePopWnd->SetContentTextWithUTF(ContentText, Color3B::BLACK);
    auto pUpdateButton=pUpdatePopWnd->SetCompleteButton("confirm_Blasting.png", "confirm_Blasting1.png", "confirm_Blasting.png");
    pUpdateButton->setScale(0.5f);
    pUpdateButton->addTouchEventListener(CC_CALLBACK_2(GNS_LoginScene::BtnCallBack, this));
    pUpdateButton->setTag(2);
    
    pUpdatePopWnd->GetCloseButton()->setPosition(Vec2(pUpdateButton->getPositionX()*2.5, pUpdateButton->getPositionY()));
    pUpdatePopWnd->GetCloseButton()->setScale(0.5f);
}

// 事件桥定时器的回调函数
void GNS_LoginScene::onEventBridge(float dt)
{
    IEventBridge::EVENT_INFO eventInfo;
    
     while (IEventBridge::getInstance()->popFront(eventInfo))
    {
		 switch (eventInfo.iMainCode)
		 {
			 case CLIENT_INNER_CONNECT:					// 连接结果
			 {
				 int& iReconnectCount = (int&)eventInfo.szBody;
				 connectResult(eventInfo.iClientId, eventInfo.iSubCode, iReconnectCount);
				 break;
			 }
			 case CLIENT_INNER_RE_CONNECT:			// 断线重连
			 {
				 int& iReconnectCount = (int&)eventInfo.szBody;
				 reConnectResult(eventInfo.iClientId, eventInfo.iSubCode, iReconnectCount);
				 break;
			 }
			 case CLIENT_INNER_RE_CLOSE:		// 断线
			 {
				 // 断线时不需要作任何处理，断线的事项交由断线重连功能（CLIENT_INNER_RE_CONNECT）进行处理
				 break;
			 }

			 default:
			 {
				 OnHandleSocketMsg(eventInfo.iClientId, eventInfo.iMainCode, eventInfo.iSubCode, (char*)(&eventInfo.szBody), eventInfo.iBodyLen);
				 break;
			 }
		 }
    }
}

bool GNS_LoginScene::OnHandleSocketMsg(int iClientId, int mainCmd, int subCmd, const char *msgData, int dataLen)
{
    switch (subCmd)
    { 
        case SUB_SG_VERSION_REEOR:
        {
			assert(sizeof(CMD_VerError) == dataLen);
			if (sizeof(CMD_VerError) != dataLen)
				return false;

			CMD_VerError * pVerError = (CMD_VerError*)msgData;

            log("Version==%d",pVerError->iVersion);
            if (pVerError->iVersion!=GNS_PlayerMgr::getInstance()->getCurrentVersionClient()) 
			{
                GNS_PlayerMgr::getInstance()->setServerVersion(pVerError->iVersion);

				#if (CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
								GNS_PlayerMgr::getInstance()->setUpdateURL(pVerError->szAppDownAddr);
				#elif (CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID)
								GNS_PlayerMgr::getInstance()->setUpdateURL(pVerError->szAndrDownAddr);
				#else
								GNS_PlayerMgr::getInstance()->setUpdateURL(pVerError->szPCDownAddr);
				#endif

            }
            auto pLoginLayers = (GNS_LoginScene*)GNS_SceneMgr::getInstance()->getSceneLayer(LOGIN_LAYER);
            pLoginLayers->GameUpdae();
            break;
        }
        case SUB_SC_USER_LOGIN_SUC://用户登录成功
        {
			assert(sizeof(CMD_SC_AgentUserLoginInfo) == dataLen);
			if (sizeof(CMD_SC_AgentUserLoginInfo) != dataLen)
				return false;

            CMD_SC_AgentUserLoginInfo * pLoginMsg = (CMD_SC_AgentUserLoginInfo*)(msgData);

            GNS_PlayerMgr::getInstance()->setMyUseridx(pLoginMsg->llAgentID);
            GNS_PlayerMgr::getInstance()->setMyNickName(pLoginMsg->szName);
            GNS_PlayerMgr::getInstance()->setUserLevel(pLoginMsg->nAgentLevel);
            GNS_PlayerMgr::getInstance()->setPlayTop(pLoginMsg->_playerRechargeScale);
            
            break;
        }
        case SUB_SC_USER_LOGIN_FINISH:// 用户登录完成
        {
            auto pLoginLayers = (GNS_LoginScene*)GNS_SceneMgr::getInstance()->getSceneLayer(LOGIN_LAYER);
            pLoginLayers->SceneJump();
            break;
        }
        case SUB_SC_USER_LOGIN_FAIL:// 用户登录失败
        {
			assert(sizeof(CMD_SC_UserLoginFail) == dataLen);
			if (sizeof(CMD_SC_UserLoginFail) != dataLen)
				return false;

            CMD_SC_UserLoginFail * ploginFail = (CMD_SC_UserLoginFail*)(msgData);

            OnUIAction(ploginFail->szResText, false);
            auto pLoginLayers = (GNS_LoginScene*)GNS_SceneMgr::getInstance()->getSceneLayer(LOGIN_LAYER);
            pLoginLayers->LoginFile();
            
            break;
        }
        case SUB_SC_USER_GETUSERINFO_FINISH: //获取个人信息
        {
			assert(sizeof(CMD_SC_GetMobileUserinfoResult) == dataLen);
			if (sizeof(CMD_SC_GetMobileUserinfoResult) != dataLen)
					return false;

            CMD_SC_GetMobileUserinfoResult * pUserinfo = (CMD_SC_GetMobileUserinfoResult*)(msgData);

            if (pUserinfo) 
			{
                GNS_PlayerMgr::getInstance()->pGetUserInfoResult = *pUserinfo;
            }
            break;
        }
        case SUB_SC_USER_GETUSERINFO_ERROR: //获取个人信息失败
        {
			assert(sizeof(CMD_SC_GetAgentUserInfoFail) == dataLen);
			if (sizeof(CMD_SC_GetAgentUserInfoFail) != dataLen)
				return false;

            CMD_SC_GetAgentUserInfoFail * pUserInfoFail = (CMD_SC_GetAgentUserInfoFail*)(msgData);

            if (pUserInfoFail) 
			{
                OnUIAction(pUserInfoFail->szResText, false);
            }

            break;
        }
        case SUB_SC_GAME_HALL_LIST_SUCC:
        {
			assert(sizeof(CMD_SC_HALLGAME_LIST) == dataLen);
			if (sizeof(CMD_SC_HALLGAME_LIST) != dataLen)
				return false;

            CMD_SC_HALLGAME_LIST * pHallGameList = (CMD_SC_HALLGAME_LIST*)(msgData);

            if (pHallGameList) 
			{
                GNS_PlayerMgr::getInstance()->setGameList(pHallGameList);
            }
            break;
        }
        case SUB_SC_GAME_HALL_LIST_ERROR:
        {
            OnUIAction("获取游戏列表失败", true);
            break;
        }
        case SUB_SC_GET_REMARK_NAME_SUC://获取备注名
           
        {
			assert(sizeof(CMD_SC_GetRemarkNameResult) == dataLen);
			if (sizeof(CMD_SC_GetRemarkNameResult) != dataLen)
				return false;

            CMD_SC_GetRemarkNameResult * pGetRemark = (CMD_SC_GetRemarkNameResult*)(msgData);

            if (pGetRemark) 
			{
                GNS_PlayerMgr::getInstance()->setRemarkName(pGetRemark);
            }

            break;
        }
		case SUB_SC_GET_REMARK_NAME_FAIL:  //获取备注名失败
		{
				int iTmp = 0;
				break;
		}
        case SUB_SC_GET_REMARK_NAME_FINISH://获取备注名 完成
        {
		   int iTmp = 0;
            break;
        }
        case SUB_SC_GET_LOWLINE_RECHARGE_RATIO_SUC: //获取下线充值比成功
        case SUB_SC_GET_LOWLINE_RECHARGE_RATIO_FAIL://获取下线充值比失败
        {
			assert(sizeof(CMD_SC_GetAgentRechargeRatioResult) == dataLen);
			if (sizeof(CMD_SC_GetAgentRechargeRatioResult) != dataLen)
				return false;

            CMD_SC_GetAgentRechargeRatioResult * pGetAgentRation  = (CMD_SC_GetAgentRechargeRatioResult*)(msgData);

            if (pGetAgentRation) 
			{
                if (pGetAgentRation->_retVal==1) 
				{
					OnUIAction(pGetAgentRation->_remark, false);
                }
				else
				{
                    GNS_PlayerMgr::getInstance()->setAgRation(pGetAgentRation);
                }
            }
            break;
        }
        case SUB_SC_GET_LOWLINE_RECHARGE_RATIO_FINISH://获取下线充值比完成
        {
            break;
        }
		case SUB_SC_GET_LOWLINE_INFO_SUC:
		{
			assert(sizeof(CMD_SC_GetLowlineInfoResult) == dataLen);
			if (sizeof(CMD_SC_GetLowlineInfoResult) != dataLen)
				return false;
			CMD_SC_GetLowlineInfoResult *pLowlineInfo = (CMD_SC_GetLowlineInfoResult*)(msgData);
			if (pLowlineInfo != nullptr)
			{
				GNS_PlayerMgr::getInstance()->setUpToLowCode(pLowlineInfo->_lowlineCode, pLowlineInfo->_uplineCode);
				GNS_PlayerMgr::getInstance()->setCodeAndRatio(pLowlineInfo->_lowlineCode, pLowlineInfo->_lowlineRechargeRatio);
			}
			break;
		}
		case SUB_SC_GET_LOWLINE_INFO_FINISH:
		{
			break;
		}
        default:  break;
    }
}

void GNS_LoginScene::login()
{
	//if (pResult->iConnect)
	
		CMD_CS_AgentUserLogin loginInfo;
#if (CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID)
		loginInfo.iPlatformNo = 100;
#elif (CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
		loginInfo.iAppId = 104;
#else
		loginInfo.iAppId = 105;
#endif
		memcpy(loginInfo.szAgentName, _NameText->getText(), 33);
		char PassWord[33] = { 0 };
		memcpy(PassWord, _PassText->getText(), 33);
		memcpy(loginInfo.szPwd, SystemMgr::getInstance()->md5String(PassWord), 33);
		loginInfo.iPlatformNo = 1;
		loginInfo.iVersion = GNS_PlayerMgr::getInstance()->getCurrentVersionClient();
		loginInfo.iTrenchId = 0;

		int ret = GnsClientFrame::getInstance()->sendMsg(0, MAIN_MSG_LOGIN, SUB_CS_USER_LOGIN, (char*)(&loginInfo), sizeof(loginInfo));
		int b = 0;
	
	//else
	/*
	{
		if (pResult->iReconnectCount > RE_CONNECT_COUNT)  // 用宏取代 20
		{
			// 连接失败的提示框
			this->unschedule(schedule_selector(GNS_LoginScene::onEventBridge));
			//log("连接失败");
			auto  pPopWnd = PopWndLayer::createScene("Popwnd.png", "PageClose.png");
			pPopWnd->setClickWndOutsideClose(true);
			pPopWnd->SetTitle("提示!");
			pPopWnd->SetContentText("与服务器连接失败，请重试！", Color3B::BLACK);
			pInfoMakeLayer->Show(false);
			

		}*/
	//}
}

PopWndLayer * GNS_LoginScene::OnUIAction(std::string Text,bool isUTF)
{
    pPopWnd = PopWndLayer::createScene("Popwnd.png", "PageClose.png");
    pPopWnd->setClickWndOutsideClose(true);
    pPopWnd->SetTitleWithUTF("提示!");
	if (isUTF)
		pPopWnd->SetContentTextWithUTF(Text, Color3B::BLACK);
	else
		pPopWnd->SetContentTextWithGB(Text, Color3B::BLACK);
    //pPopWnd->PopWndEffectseffects("RunCircle.plist",Effect);
    return pPopWnd;
}

// 连接结果
int GNS_LoginScene::connectResult(int iClientId, int iSubCode, int iReconnectCount)
{
	switch (iSubCode)
	{
		case CC_START_NO_CIRCLE:				// 在 开始转圈的连接次数 以内，不转圈
		{
			log("CLIENT_INNER_CONNECT,  CC_START_NO_CIRCLE  %d", iReconnectCount);
			break;
		}
			case CC_CONNECT_CIRCLE_ING:		// 在  >开始转圈的连接次数 并且  <=结束转圈的连接次数 范围，开始转圈【正在连接】
		{
			log("CLIENT_INNER_CONNECT,  CC_CONNECT_CIRCLE_ING  %d", iReconnectCount);
			if (pInfoMakeLayer == nullptr)
			{
				pInfoMakeLayer = GNS_MakeLayer::CreateMakeLayer("加载中...");

				//this->addChild(pInfoMakeLayer);
				addMakerLayer();
			}
				

			break;
		}
			case CC_SUCC_NO_CIRCLE:				// 连接成功，结束转圈
		{
			log("CLIENT_INNER_CONNECT,  CC_SUCC_NO_CIRCLE  %d", iReconnectCount);
			login();
			flag = false;
			if (pInfoMakeLayer!=nullptr)
				pInfoMakeLayer->Show(false); 
			break;
		}
			case CC_FAIL_NO_CIRCLE:					// 结束转圈，并弹出【连接失败】的提示框
		{
			log("CLIENT_INNER_CONNECT,  CC_FAIL_NO_CIRCLE  %d", iReconnectCount);

			// 连接失败的提示框
			if (pInfoMakeLayer != nullptr)
				pInfoMakeLayer->Show(false);
			this->unschedule(schedule_selector(GNS_LoginScene::onEventBridge));
			//log("连接失败");
			auto  pPopWnd = PopWndLayer::createScene("Popwnd.png", "PageClose.png");
			pPopWnd->setClickWndOutsideClose(true);
			pPopWnd->SetTitleWithUTF("提示!");
			pPopWnd->SetContentTextWithUTF("与服务器连接失败，请重试！", Color3B::BLACK);
			

			break;
		}
		default:
			break;
}

return 0;
}

void GNS_LoginScene::addMakerLayer()
{
	if (!flag)
	{
		this->addChild(pInfoMakeLayer);
		flag = true;
	}
}

// 断线重连
int GNS_LoginScene::reConnectResult(int iClientId, int iSubCode, int iReconnectCount)
{
	switch (iSubCode)
	{
		case RECC_START_NO_CIRCLE:				// 在 开始转圈的连接次数 以内，不转圈
	{
		log("CLIENT_INNER_RE_CONNECT,  RECC_START_NO_CIRCLE  %d", iReconnectCount);
		break;
	}
		case RECC_CONNECT_CIRCLE_ING:	// 在  >开始转圈的连接次数 并且  <=结束转圈的连接次数 范围，开始转圈【正在连接】
	{
		log("CLIENT_INNER_RE_CONNECT, RECC_CONNECT_CIRCLE_ING  %d", iReconnectCount);
		break;
	}
		case RECC_SUCC_NO_CIRCLE:			// 连接成功，结束转圈
	{
		log("CLIENT_INNER_RE_CONNECT,  RECC_SUCC_NO_CIRCLE  %d", iReconnectCount);
		break;
	}
		case RECC_FAIL_NO_CIRCLE:				// 结束转圈，并弹出【连接失败】的提示框
	{
		log("CLIENT_INNER_RE_CONNECT,  RECC_FAIL_NO_CIRCLE  %d", iReconnectCount);
		break;
	}
}

return 0;
}

bool GNS_LoginScene::checkInput()
{
	string pass = _PassText->getText();
	string name = _NameText->getText();
	if (CCGnsOften::checkPassWord(pass) && CCGnsOften::checkMgrID(name))
		return true;
		
	OnUIAction("输入信息有误！", true);
	return false;
}
